﻿using System;
using System.Collections.Generic;

namespace CatEars.Core.UI.Displays
{
    /// <summary>
    /// 将需要显示到界面的对象缓存下来，然后通过Timeer或者其它方式展示到界面上
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class ItemsDisplayBase<T>
    {
        /// <summary>
        /// 将单个对象推给界面，第二个参数：是否是本批次最后一个对象
        /// </summary>
        protected Action<T, bool> _pushItem;
        /// <summary>
        /// 批量将对象推给界面
        /// </summary>
        protected Action<ICollection<T>> _pushItems;
        LinkedList<T> _innerList = new LinkedList<T>();

        /// <summary>
        /// 更新间隔(毫秒)
        /// </summary>
        public abstract int Interval { get; set; }

        /// <summary>
        /// 初始化ItemsDisplayBase
        /// </summary>
        /// <param name="pushItem">将单个对象推给界面，第二个参数：是否是本批次最后一个对象</param>
        public ItemsDisplayBase(Action<T, bool> pushItem)
        {
            _pushItem = pushItem;
        }

        /// <summary>
        /// 初始化ItemsDisplayBase(批量版)
        /// </summary>
        /// <param name="pushItems">批量将对象推给界面</param>
        public ItemsDisplayBase(Action<ICollection<T>> pushItems)
        {
            _pushItems = pushItems;
        }

        /// <summary>
        /// 取出在innerList中所有对象 并重置innerList
        /// </summary>
        /// <returns></returns>
        protected LinkedList<T> GetItemList()
        {
            if (_innerList.Count == 0)
            {
                return null;
            }
            LinkedList<T> listTmp;
            lock (_innerList)
            {
                listTmp = _innerList;
                _innerList = new LinkedList<T>();
                return listTmp;
            }
        }

        /// <summary>
        /// 单个Push的TimerTick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void PushItemTimerTick(object sender, EventArgs e)
        {
            if (_pushItem == null) return;
            LinkedList<T> listTmp = GetItemList();
            if (listTmp.IsNullOrEmptyT()) return;
            var node = listTmp.First;
            while (node != null)
            {
                _pushItem(node.Value, node.Next == null);
                node = node.Next;
            }
        }

        /// <summary>
        /// 批量Push的TimerTick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void PushItemsTimerTick(object sender, EventArgs e)
        {
            if (_pushItems == null) return;
            LinkedList<T> listTmp = GetItemList();
            if (listTmp.IsNullOrEmptyT()) return;
            _pushItems(listTmp);
        }

        /// <summary>
        /// 开始Timer的运行
        /// </summary>
        public abstract void Start();
        /// <summary>
        /// 停止Timer的运行
        /// </summary>
        public abstract void Stop();

        /// <summary>
        /// 设置为false之后所有add方法失效
        /// </summary>
        public bool CanAdd { get; set; } = true;

        /// <summary>
        /// 添加单个对象
        /// </summary>
        /// <param name="obj"></param>
        public void Add(T obj)
        {
            if (!CanAdd) return;
            lock (_innerList)
            {
                if (!CanAdd) return;
                _innerList.AddLast(obj);
            }
        }

        /// <summary>
        /// 添加多个对象
        /// </summary>
        /// <param name="objs"></param>
        public void AddRange(IEnumerable<T> objs)
        {
            if (!CanAdd) return;
            if (objs == null) return;
            lock (_innerList)
            {
                if (!CanAdd) return;
                foreach (var item in objs)
                {
                    _innerList.AddLast(item);
                }
            }
        }
    }
}
